package com.hzy.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzy.system.domain.SysFunction;
import com.hzy.system.domain.SysMenu;
import com.hzy.system.domain.SysMenuFunction;
import com.hzy.system.domain.SysRoleMenuFunction;
import com.hzy.system.domain.vo.SysRoleMenuFunctionVo;
import com.hzy.system.mapper.ISysMenuMapper;
import com.hzy.system.mapper.ISysRoleMenuFunctionMapper;
import com.hzy.system.service.ISysFunctionService;
import com.hzy.system.service.ISysMenuFunctionService;
import com.hzy.system.service.ISysRoleMenuFunctionService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author HZY
 * @since 2020-04-29
 */
@Service
public class SysRoleMenuFunctionServiceImpl extends ServiceImpl<ISysRoleMenuFunctionMapper, SysRoleMenuFunction>
        implements ISysRoleMenuFunctionService {
    private final ISysFunctionService functionService;
    private final ISysMenuFunctionService menuFunctionService;
    private final ISysMenuMapper sysMenuMapper;

    public SysRoleMenuFunctionServiceImpl(ISysFunctionService functionService,
                                          ISysMenuFunctionService menuFunctionService,
                                          ISysMenuMapper sysMenuMapper) {

        this.functionService = functionService;
        this.menuFunctionService = menuFunctionService;
        this.sysMenuMapper = sysMenuMapper;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String saveForm(List<SysRoleMenuFunctionVo> form) {
        List<SysRoleMenuFunction> sysRoleMenuFunctions = new ArrayList<>();
        String roleId = form.size() > 0 ? form.get(0).getRoleId() : null;

        if (ObjectUtils.isEmpty(roleId)) {
            return null;
        }

        this.lambdaUpdate()
                .eq(SysRoleMenuFunction::getRoleId, roleId)
                .in(SysRoleMenuFunction::getMenuId, form.stream().map(SysRoleMenuFunctionVo::getMenuId).collect(Collectors.toList()))
                .remove()
        ;

        for (SysRoleMenuFunctionVo sysRoleMenuFunctionVo : form) {
            for (String functionId : sysRoleMenuFunctionVo.getFunctionIds()) {
                SysRoleMenuFunction model = new SysRoleMenuFunction();
                model.setFunctionId(functionId);
                model.setMenuId(sysRoleMenuFunctionVo.getMenuId());
                model.setRoleId(sysRoleMenuFunctionVo.getRoleId());

                sysRoleMenuFunctions.add(model);
            }
        }

        this.saveOrUpdateBatch(sysRoleMenuFunctions);
        return roleId;
    }

    /**
     * 根据角色id 获取角色菜单功能
     *
     * @param roleId
     * @return
     */
    @Override
    public List<Map<String, Object>> getRoleMenuFunctionByRoleId(String roleId) {
        List<SysMenu> allMenus = this.sysMenuMapper.selectList(new LambdaQueryWrapper<SysMenu>().orderByAsc(SysMenu::getNumber));
        List<SysFunction> allFunctions = this.functionService.lambdaQuery().orderByAsc(SysFunction::getNumber).list();
        List<SysMenuFunction> allMenuFunction = this.menuFunctionService.lambdaQuery().orderByAsc(SysMenuFunction::getCreationTime).list();
        List<SysRoleMenuFunction> allRoleMenuFunction = this.lambdaQuery().eq(SysRoleMenuFunction::getRoleId, roleId).list();

        List<Map<String, Object>> result = new ArrayList<>();

        for (SysMenu item : allMenus) {
            //组装菜单
            List<SysMenuFunction> sysMenuFunctions = allMenuFunction
                    .stream().filter(w -> item.getId().equals(w.getMenuId()))
                    .collect(Collectors.toList());

            //获取菜单拥有的按钮数组
            List<String> functionIds = sysMenuFunctions.stream().map(SysMenuFunction::getFunctionId).collect(Collectors.toList());
            List<Map<String, Object>> sysFunctions = allFunctions
                    .stream().filter(w -> functionIds.contains(w.getId()))
                    .map(w -> {
                        Map<String, Object> res = new HashMap<>(2);
                        res.put("id", w.getId());
                        res.put("label", w.getName());
                        return res;
                    })
                    .collect(Collectors.toList());

            //获取当前角色勾选该菜单的按钮集合
            List<String> checkedFunctionIds = allRoleMenuFunction
                    .stream().filter(w -> item.getId().equals(w.getMenuId()))
                    .map(SysRoleMenuFunction::getFunctionId)
                    .collect(Collectors.toList());

            //集合项
            Map<String, Object> map = new HashMap<>(10);
            map.put("id", item.getId());
            map.put("name", item.getName());
            map.put("number", item.getNumber());
            map.put("parentId", item.getParentId());
            map.put("levelCode", item.getLevelCode());
            map.put("menuFunctions", sysFunctions);
            map.put("checkedFunctionIds", checkedFunctionIds);
            map.put("checkAll", checkedFunctionIds.size() > 0 && (sysFunctions.size() == checkedFunctionIds.size()));
            map.put("indeterminate", checkedFunctionIds.size() > 0 && checkedFunctionIds.size() < sysFunctions.size());

            result.add(map);
        }

        return result;
    }

}
